package cn.com.anysdk.oss.impl;

import cn.com.anysdk.oss.api.IOssConfig;
import cn.com.anysdk.oss.api.IOssService;
import cn.com.anysdk.oss.exception.OssException;
import cn.com.anysdk.oss.factory.OssServiceFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

/**
 * OSS服务管理器
 * 负责管理OSS服务的创建、切换和配置验证
 */
@Slf4j
public class OssServiceManager {
    private final ConcurrentHashMap<String, IOssService> serviceCache = new ConcurrentHashMap<>();
    private IOssService currentService;
    private IOssConfig currentConfig;

    /**
     * 切换存储服务提供商
     * @param config 新的服务商配置
     * @return 切换后的OSS服务实例
     */
    public synchronized IOssService switchProvider(IOssConfig config) {
        try {
            // 验证配置
            if (!validateConfig(config)) {
                throw new OssException("Invalid OSS configuration");
            }

            String provider = config.getProvider();
            log.info("Switching OSS provider to: {}", provider);

            // 检查缓存中是否已存在该服务商的实例
            IOssService service = serviceCache.get(provider);
            if (service == null) {
                // 创建新的服务实例
                service = OssServiceFactory.createService(config);
                serviceCache.put(provider, service);
            }

            // 更新当前服务实例和配置
            this.currentService = service;
            this.currentConfig = config;

            log.info("Successfully switched to provider: {}", provider);
            return service;
        } catch (Exception e) {
            log.error("Failed to switch OSS provider", e);
            throw new OssException("Failed to switch OSS provider: " + e.getMessage(), e);
        }
    }

    /**
     * 获取当前服务商配置
     * @return 当前服务商配置
     */
    public IOssConfig getCurrentConfig() {
        return currentConfig;
    }

    /**
     * 获取当前OSS服务实例
     * @return 当前OSS服务实例
     */
    public IOssService getCurrentService() {
        if (currentService == null) {
            throw new OssException("No OSS service is currently configured");
        }
        return currentService;
    }

    /**
     * 验证服务商配置是否有效
     * @param config 待验证的配置
     * @return 配置是否有效
     */
    public boolean validateConfig(IOssConfig config) {
        if (config == null) {
            return false;
        }

        String provider = config.getProvider();
        if (provider == null || provider.trim().isEmpty()) {
            return false;
        }

        // 根据不同服务商验证必要的配置项
        return switch (provider.toLowerCase()) {
            case "aliyun" -> validateAliyunConfig(config);
            case "tencent" -> validateTencentConfig(config);
            case "minio" -> validateMinioConfig(config);
            case "local" -> validateLocalConfig(config);
            default -> false;
        };
    }

    private boolean validateAliyunConfig(IOssConfig config) {
        return config.getAccessKeyId() != null && !config.getAccessKeyId().trim().isEmpty() &&
               config.getAccessKeySecret() != null && !config.getAccessKeySecret().trim().isEmpty() &&
               config.getEndpoint() != null && !config.getEndpoint().trim().isEmpty() &&
               config.getBucketName() != null && !config.getBucketName().trim().isEmpty();
    }

    private boolean validateTencentConfig(IOssConfig config) {
        return config.getAccessKeyId() != null && !config.getAccessKeyId().trim().isEmpty() &&
               config.getAccessKeySecret() != null && !config.getAccessKeySecret().trim().isEmpty() &&
               config.getEndpoint() != null && !config.getEndpoint().trim().isEmpty() &&
               config.getBucketName() != null && !config.getBucketName().trim().isEmpty();
    }

    private boolean validateMinioConfig(IOssConfig config) {
        return config.getAccessKeyId() != null && !config.getAccessKeyId().trim().isEmpty() &&
               config.getAccessKeySecret() != null && !config.getAccessKeySecret().trim().isEmpty() &&
               config.getEndpoint() != null && !config.getEndpoint().trim().isEmpty() &&
               config.getBucketName() != null && !config.getBucketName().trim().isEmpty();
    }

    private boolean validateLocalConfig(IOssConfig config) {
        return config.getEndpoint() != null && !config.getEndpoint().trim().isEmpty();
    }
} 